package gateway.filter;

import com.alibaba.fastjson.JSON;
import gateway.dto.ResponseResult;
import gateway.enums.ResponseCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.cors.reactive.CorsUtils;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * @author Ezio.Auditore
 * @date 2020-03-08
 */
@Slf4j
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {

    private static final String LOGIN_URL = "/oauth/token";
    private static final String SWAGGER = "doc.html";
    private static final String JS = "js";
    private static final String CSS = "css";
    private static final String HTML = "html";
    private static final String ICO = "ico";
    private static final String RESOURCE = "swagger-resources";
    private static final String API = "api-docs";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest serverHttpRequest = exchange.getRequest();
        ServerHttpResponse serverHttpResponse = exchange.getResponse();
        String uri = serverHttpRequest.getURI().getPath();

        //  检查白名单（配置）
        log.info("判断是否是白名单路径");
        if (uri.indexOf(LOGIN_URL) >= 0 ||
                uri.indexOf(SWAGGER) >= 0 ||
                uri.indexOf(JS) >= 0 ||
                uri.indexOf(CSS) >= 0 ||
                uri.indexOf(HTML) >= 0 ||
                uri.indexOf(ICO) >= 0 ||
                uri.indexOf(RESOURCE) >= 0 ||
                uri.indexOf(API) >= 0) {
            log.info("是白名单,放行~");
            return chain.filter(exchange);
        }

        log.info("不是白名单,查看是否携带token");
        String token = serverHttpRequest.getHeaders().getFirst("token");
        if (StringUtils.isBlank(token)) {
            log.info("没携带token,返回失败信息");
            serverHttpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
            return getVoidMono(serverHttpResponse, ResponseCodeEnum.TOKEN_MISSION);
        } else {
            log.info("携带token,放行");
            return chain.filter(exchange);
        }
    }

    private Mono<Void> getVoidMono(ServerHttpResponse serverHttpResponse, ResponseCodeEnum responseCodeEnum) {
        serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        ResponseResult responseResult = ResponseResult.error(responseCodeEnum.getCode(), responseCodeEnum.getMessage());
        DataBuffer dataBuffer = serverHttpResponse.bufferFactory().wrap(JSON.toJSONString(responseResult).getBytes());
        return serverHttpResponse.writeWith(Flux.just(dataBuffer));
    }

    @Override
    public int getOrder() {
        return -100;
    }

}